-- lua list searcher.

require"luasql.mysql"
dofile"db.lua"
dofile"search.lua"
dofile"string.lua"


function diagonal(t)
	local copy = {}
	for k, v in next, t do
		copy[k]=v
	end
	for k, v in next, copy do
		t[v]=k
	end
	
	return t
end


local months = diagonal{
	Jan = 1,
	Feb = 2, 
	Mar = 3, 
	Apr = 4, 
	May = 5, 
	Jun = 6, 
	Jul = 7, 
	Aug = 8, 
	Sep = 9, 
	Oct = 10, 
	Nov = 11, 
	Dec = 12
}







message = {}

function message.print(m)
	for k, v in next, m do
		print(k .. "\t: ".. v)
	end
	print("=============================\n")
end

function date_tostring(d)
	return d.day.." "..d.month.." "..d.year --.." : "..date_tomysql(d)
end

function pad(s)
	s = tostring(s)
	return (string.len(s) == 1 and "0"..s or s)
end

function date_tomysql(d)
	local s = d.year.."-"..pad(months[tonumber(d.month) or d.month]).."-"..pad(d.day)
	s=s.." "..d.hour.."-"..d.minute.."-"..d.second
	--print("Date?:"..s)
	return s
end

function get_html(m)
	local s = '<div class="message">'
	s = s ..'<dl>'
	s = s ..'<dt>To</dt><dd>' .. m.from .. '</dd>'
	s = s ..'<dt>From</dt><dd>' .. (m.to or 'unkown') .. '</dd>'
	s = s ..'<dt>Subject</dt><dd>' .. m.subject .. '</dd>'
	s = s ..'<dt>Date</dt><dd>' .. date_tostring(m.date) .. '</dd>'
	s = s ..'<dt>Message</dt><dd><pre>' .. string.gsub(string.gsub(m.message, "<", "&gt;"), ">", "&lt;") .. '</pre></dd>'
	s = s..'</dl></div>'
	return s
end

function index_search()
	return search.build_index()
end

--[[
--	Read an email message from the open file 'f'
--]]

function read_message(f)
	local m = {}
	local line = f:read()
	m.last = nil
	-- read metadata
	while string.sub(line, 0, 8) ~= 'Status: ' do
		read_header(line, m)
		--local prop = string.sub(line
		--print(line .. '|')
		line = f:read()
	end
	
	if read_content(f, m) then
	
	else
		if read_content(f, m) then
		
		else
			print("bugger"..line)
		end	
	end
	-- read message
				
	
	
	-- fix up date
	print("original date:"..m.date)
	m.date = parse_date(m.date)
	debug_t(m.date)
	m.date.hour = m.date.hour + (tonumber(m.date.gmt) or 0)
	--print("how is the date now?"..date_tomysql(m.date))
	debug_t(m.date)
	
	return m

end

function read_header(line, m)
	local ind = string.find(line, '[: ]')
	if ind then
		local prop = string.lower(string.gsub(string.sub(line, 0, ind -1), "-", ""))
		m[prop] = string.trim(string.sub(line, ind+1))
		m.last = prop
	else
		if m.last then
			m[m.last] = m[m.last]..string.trim(line)
		else
			--print (' no last: ' .. line)
		end
	end	
end

function read_content(f, m)
	if m.contentlength then
		m.message = f:read(tonumber(m.contentlength))
		return true
	else
		return false
	end
end

function parse_date(s, keep)
	if not(keep) then
		s = string.sub(s, 6)
	end
	parts = setmetatable({},
		{
			__index = function(t,k) return nil end
		})
	for word in s:gmatch("[%w-]+") do
		table.insert(parts, word)
	end
--	debug_t(parts)
	-- fix gmt
	if parts[7] and parts[7] ~= nil then
		parts[7] = string.gsub(parts[7], "00", "")
	end

	return {
		day = parts[1], 
		month=parts[2], 
		year=parts[3], 
		hour=parts[4],
		minute=parts[5],
		second=parts[6],
		gmt=parts[7]
	}
end

function message.save(m)
	--[[if not m.inreplyto then
		m.inreplyto = m.messageid
		if string.starts(m.subject, 'Re: ') or string.starts(m.subject, 'RE: ') then]]
	local ans, err = db.execute("INSERT INTO FixMessage(MessageID, ThreadID, Title, Date, Message) VALUES('"..m.messageid.."','"..(string.match(m.inreplyto or '', "<([^<]+)>") or '').."','"..string.gsub(m.subject, "'", "''").."','"..date_tomysql(m.date).."','"..string.gsub( m.message, "'", "''").."')")
	print(ans, err)
		--[[else
			local ans, err = db.execute("INSERT INTO Thread(MessageID, Title, Date) VALUES('"..m.messageid.."','"..string.gsub( m.subject, "'", "''").."','"..date_tomysql(m.date).."')")
			print(ans, err)

		end
	end

	local ans, err = db.execute("INSERT INTO Message(MessageID,ThreadID, Date, Message) VALUES('"..m.messageid.."','"..m.inreplyto.."','"..date_tomysql(m.date).."','"..string.gsub(m.message, "'", "''").."')")
	print(ans, err)
	]]	
end

function get_thread_cursor(id)
	return db.execute("SELECT T.Title, M.MessageID, M.Message, M.Date FROM Message M INNER JOIN Thread T ON M.ThreadID = T.MessageID WHERE T.MessageID = '"..id.."' ORDER BY M.Date DESC")
end

function message_from_row(r)
	local u = "unknown"
	return {
		from =  "unknown", 
		to = u,
		date = parse_date(r.Date, true),
		subject=r.Title, 
		message=r.Message, 
		messageid=r.MessageID
	}
end

function get_thread(id)
	local messages = {}
	local thread, err = get_thread_cursor(id)
	local t = {}
	if err then
		print(err)
		return t
	end
	while thread:fetch(t, "a") do
		
		messages[t.MessageID] = message_from_row(t)
	end
	return messages
end

function thread_index()
	local threads, err = db.execute"SELECT T.MessageID, T.Title, T.Date, COUNT(M.MessageID) AS Messages FROM Thread T INNER JOIN Message M ON T.MessageID = M.ThreadID GROUP BY T.MessageID ORDER BY M.Date DESC LIMIT 50"
	if err then print(err) end
	return threads, err
end

function get_index_html()
	local threads, err = thread_index()
	if err then
		return err
	end
	
	--cgilua.put(threads.fetch)
	
	local t = {}
	
	cgilua.put"<table>"
	cgilua.put"<tr><th>Title</th><th>Date</th><th>Posts</th></tr>"
	while threads:fetch(t, "a") do
		cgilua.put("<tr><td><a href=\"thread.lp?m="..t.MessageID.."\">"..t.Title.."</a></td>")
		cgilua.put("<td>"..(t.Date or "").."</td>")
		cgilua.put("<td>"..(t.Messages).."</td></tr>")
	end
	cgilua.put"</table>"
	return s
end

function main()
	local f = io.open('lua-l-archive', 'r')

	local m = read_message(f)
	
	message.print(m)
	
	m = read_message(f)
	message.print(m)
	
	m = read_message(f)
	message.print(m)
	
	m = read_message(f)
	message.print(m)
	m = read_message(f)
	message.print(m)
	
	f:close()

end
			
function index_archive()
			
	local f = io.open('lua-l-archive', 'r')

	for i = 1, 1000 do
		local m = read_message(f)
		message.save(m)
		--cgilua.put(get_html(m))
	end
			
end
			

-- run main if called directly
_ = arg and arg[0]=='lua-l.lua' and main()

function debug_t(tab)

	for k, v in next, tab do
		print("["..k.."]", v)

	end
end

--debug_t(months)